#ifndef __KERNEL__TYPES__HPP__
# define __KERNEL__TYPES__HPP__

namespace detail
{

    /**
     * @brief 3D-vector primitive.
     */
    template<typename Scalar>
    struct vector3_type
    {
        static vector3_type empty()
        {
            static vector3_type ret(vector3_type(0, 0, 0));
            return ret;
        }

        vector3_type(Scalar X, Scalar Y, Scalar Z) :
            x(X), y(Y), z(Z)
        {
        }

        vector3_type()
        {
            *this = empty();
        }

        vector3_type operator /(Scalar denominator) const
        {
            return vector3_type(x / denominator, y / denominator, z / denominator);
        }

        vector3_type operator *(Scalar factor) const
        {
            return vector3_type(x * factor, y * factor, z * factor);
        }

        vector3_type operator -(const vector3_type &rhs) const
        {
            return vector3_type(x - rhs.x, y - rhs.y, z - rhs.z);
        }

        vector3_type operator +(const vector3_type &rhs) const
        {
            return vector3_type(x + rhs.x, y + rhs.y, z + rhs.z);
        }

        Scalar x, y, z;
    };

    /**
     * @brief Quaternion primitive.
     */
    template<typename Scalar>
    struct quaternion_type
    {
        static quaternion_type empty()
        {
            static quaternion_type ret(quaternion_type(0, 0, 0, 0));
            return ret;
        }

        quaternion_type(Scalar W, Scalar X, Scalar Y, Scalar Z) :
            w(W), x(X), y(Y), z(Z)
        {
        }

        quaternion_type()
        {
            *this = empty();
        }

        Scalar w, x, y, z;
    };

    /**
     * @brief Color primitive.
     */
    template<typename Scalar>
    struct color_type
    {
        color_type(Scalar R, Scalar G, Scalar B, Scalar Alpha) :
            r(R), g(G), b(B), alpha(Alpha)
        {
        }
        color_type(Scalar R, Scalar G, Scalar B) :
            r(R), g(G), b(B), alpha(1.0f)
        {
        }
        Scalar r, g, b, alpha;
    };

}

typedef float scalar_t;

typedef detail::vector3_type<scalar_t> vector3_t;

typedef detail::quaternion_type<scalar_t> quaternion_t;

typedef detail::color_type<scalar_t> color_t;

struct world_transform_t
{
    vector3_t position;
    quaternion_t rotation;
};

/**
 * @brief Light primitive.
 */
struct light_t
{
    color_t diffuse;
    color_t specular;
    vector3_t position;
    vector3_t direction;
};

#endif //__KERNEL__TYPES__HPP__
